﻿using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using HDJ.Framework.Core;
using System;

namespace HDJ.Framework.Core
{
    /// <summary>
    /// 把Resource下的资源打包成.assetbundle 到StreamingAssets目录下
    /// </summary>
    public class AssetBundleBuildUtils
    {
        public static void BuildAssetBundle(string AssetBundlesOutputPath)
        {
            if (!Directory.Exists(AssetBundlesOutputPath))
            {
                Directory.CreateDirectory(AssetBundlesOutputPath);
            }

            //根据BuildSetting里面所激活的平台进行打包
            BuildPipeline.BuildAssetBundles(AssetBundlesOutputPath, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget);

            AssetDatabase.Refresh();

        }

        /// <summary>
        /// 清除之前设置过的AssetBundleName，避免产生不必要的资源也打包
        /// 之前说过，只要设置了AssetBundleName的，都会进行打包，不论在什么目录下
        /// </summary>
        public static void ClearAssetBundlesName()
        {
            string[] oldAssetBundleNames = AssetDatabase.GetAllAssetBundleNames();

            int count = oldAssetBundleNames.Length;
            for (int j = 0; j < oldAssetBundleNames.Length; j++)
            {
                AssetDatabase.RemoveAssetBundleName(oldAssetBundleNames[j], true);
                EditorUtility.DisplayProgressBar("清除Bundle名字", "进度", j / count);
            }
            EditorUtility.ClearProgressBar();
        }
        /// <summary>
        /// 设置Resources目录下所有资源的BundleName
        /// </summary>
        /// <param name="path"></param>
        /// <param name="endsWith"></param>
        public static void SetAllResourceBundleName(string path, string[] endsWith)
        {
            string[] pathArr = PathUtils.GetDirectoryFilePath(path, endsWith);

            for (int i = 0; i < pathArr.Length; i++)
            {
                string filePath = pathArr[i];
                if (filePath.EndsWith(".meta"))
                    continue;
                string s = Path.GetFileNameWithoutExtension(filePath);
                if (s == AssetsPathController.PathFileName)
                    continue;
                SetBundleName(filePath);
            }

            Debug.Log("bundleName数目：" + bundleNameDics.Count);

            int index = 0;
            int count = bundleNameDics.Count;
            foreach (var item in bundleNameDics)
            {
                index++;
                item.Key.assetBundleName = item.Value;
                EditorUtility.DisplayProgressBar("设置Bundle名字", "进度", index / count);
            }
            bundleNameDics.Clear();
            EditorUtility.ClearProgressBar();
        }

        private const string ResPathDirName = "Assets/Resources/";
        private const string EditorDirName = "/Editor/";
        private static Dictionary<AssetImporter, string> bundleNameDics = new Dictionary<AssetImporter, string>();
        private static void SetBundleName(string filePath)
        {
            if (filePath.Contains(EditorDirName))
                return;

            AssetImporter assetImporter = AssetImporter.GetAtPath(filePath);
            Type assetImporterType = assetImporter.GetType();


            if (assetImporter)
            {
                if (assetImporterType == typeof(MonoImporter))
                    return;
                if (bundleNameDics.ContainsKey(assetImporter))
                    return;

                 string bundleName = null;
                //Resources 文件夹下面资源的命名方式
                if (filePath.Contains(ResPathDirName))
                {
                    bundleName = PathUtils.CutPath(filePath, "Resources");
                    bundleName = bundleName.Replace(Path.GetExtension(bundleName), UpdateAssetsConst.EndsWith_assetbundle);
                   // assetImporter.assetBundleName = bundleName;
                    
                }
                else
                {
                    string dir = Path.GetDirectoryName(filePath);
                    dir = dir.Replace("\\", "/");
                    bundleName = dir + "/" + dir.Replace("/", "_") + UpdateAssetsConst.EndsWith_assetbundle;

                }
                bundleNameDics.Add(assetImporter, bundleName);

                if (assetImporterType == typeof(AudioImporter))
                    return;
                if (assetImporterType == typeof(TextureImporter))
                    return;
                if (assetImporterType == typeof(ShaderImporter))
                    return;
                Type assetType = AssetDatabase.GetMainAssetTypeAtPath(filePath);

                if (assetType == typeof(TextAsset))
                    return;
                if (assetType == typeof(AnimationClip))
                    return;
                string[] deps = AssetDatabase.GetDependencies(filePath);
                foreach (var tempPath in deps)
                {
                    if (tempPath.Contains(ResPathDirName))
                    {
                        continue;
                    }
                    SetBundleName(tempPath);
                }

            }
        }

        public static void SetPakagOneBundleName(string path, string[] endsWith)
        {
            string[] pathArr = PathUtils.GetDirectoryFilePath(path, endsWith);
            string bundleName = PathUtils.CutPath(path, "Resources") + "/" + Path.GetFileName(path) + UpdateAssetsConst.EndsWith_assetbundle;
            Debug.Log(bundleName);
            for (int i = 0; i < pathArr.Length; i++)
            {
                AssetImporter assetImporter = AssetImporter.GetAtPath(pathArr[i]);
                if (assetImporter)
                    assetImporter.assetBundleName = bundleName;
            }
        }
        /// <summary>
        /// 创建bundle信息
        /// </summary>
        /// <param name="settingData"></param>
        public static void CreateBundleVersionFile(string assetPath, AssetBundleInfo assetBundleInfo)
        {
            if (assetPath[assetPath.Length - 1] != '/')
                assetPath += "/";
            string data = JsonUtils.ToJson(assetBundleInfo);
            FileUtils.CreateTextFile(assetPath + UpdateAssetsConst.AssetBundleInfoFileName, data);
        }

        /// <summary>
        /// 创建资源路径文件
        /// </summary>
        /// <param name="assetPath"></param>
        /// <param name="endsWith"></param>
        public static void CreateAllResPathInfo(string assetPath, string[] endsWith = null)
        {
            assetPath = assetPath.Replace("\\", "/");
            if (assetPath[assetPath.Length - 1] != '/')
                assetPath += "/";
            if (!Directory.Exists(assetPath))
            {
                // Directory.CreateDirectory(assetPath);
                return;
            }
            string[] pathArray = PathUtils.GetDirectoryFilePath(assetPath, endsWith);

            Dictionary<string, string> dic = new Dictionary<string, string>();
            foreach (string s in pathArray)
            {
                string extension = Path.GetExtension(s);
                if (extension == ".meta")
                    continue;

                string path = s.Replace(assetPath, "");
                string name = Path.GetFileNameWithoutExtension(s).ToLower();

                if (dic.ContainsKey(name))
                {
                    Debug.LogError("资源文件名重复! " + name + " [ " + path + "]   [" + dic[name] + "]");
                }
                else
                {
                    dic.Add(name, path);
                }
            }
            string data = JsonUtils.ToJson(dic);
            //int index = 0;
            //foreach (var item in dic)
            //{
            //    data += item.Key + "," + item.Value;
            //    if (index < dic.Count - 1)
            //    {
            //        data += "\r\n";
            //    }
            //    index++;
            //}
            FileUtils.CreateTextFile(assetPath + UpdateAssetsConst.PathFileName, data);
            AssetDatabase.Refresh();
            Debug.Log("创建资源路径文件");

            if (EditorFramework.OnRecreatePathFile != null)
            {
                EditorFramework.OnRecreatePathFile();
            }
        }
        /// <summary>
        ///StreamingAssets下 创建资源路径文件
        /// </summary>
        /// <param name="assetPath"></param>
        /// <param name="endsWith"></param>
        /// <param name="platformFolderName"></param>
        public static void CreateAllResPathInfo_StreamingAssets(string assetPath, string[] endsWith, string platformFolderName)
        {
            assetPath = assetPath.Replace("\\", "/");
            if (assetPath[assetPath.Length - 1] != '/')
                assetPath += "/";
            if (!Directory.Exists(assetPath))
            {
                Directory.CreateDirectory(assetPath);
            }
            string[] pathArray = PathUtils.GetDirectoryFilePath(assetPath, endsWith);

            Dictionary<string, string> dic = new Dictionary<string, string>();
            foreach (string s in pathArray)
            {
                string extension = Path.GetExtension(s);
                if (extension == ".meta")
                    continue;

                string path = s.Replace(assetPath, "");
                string name = Path.GetFileNameWithoutExtension(s);
                if (name == platformFolderName && string.IsNullOrEmpty(extension))
                {
                    name = name + "_AssetBundleManifest";
                }
                name = name.ToLower();
                if (dic.ContainsKey(name))
                {
                    Debug.LogError("资源文件名重复! " + name + " [ " + path + "]   [" + dic[name] + "]");
                }
                else
                {
                    dic.Add(name, path);
                }
            }
            string data = JsonUtils.ToJson(dic);
            FileUtils.CreateTextFile(assetPath + UpdateAssetsConst.PathFileName, data);
            AssetDatabase.Refresh();
            Debug.Log("创建资源路径文件");
        }

        public static Dictionary<string, string> GetPathFileData(string path)
        {
            string data = FileUtils.LoadTextFileByPath(path);

            Dictionary<string, string> dir = JsonUtils.FromJson<Dictionary<string, string>>(data);
            return dir;
        }

        /// <summary>
        /// 创建资源MD5和路径文件
        /// </summary>
        /// <param name="assetPath"></param>
        /// <param name="endsWith"></param>
        public static void CreateAllResMD5AndPath(string assetPath, string[] endsWith, string platformFolderName)
        {
            if (assetPath[assetPath.Length - 1] != '/')
                assetPath += "/";
            string[] pathArray = PathUtils.GetDirectoryFilePath(assetPath, endsWith);
            //pathArray = PathUtils.RemovePathWithEnds(pathArray, new string[] { ".meta" });
            Dictionary<string, string> dic = new Dictionary<string, string>();

            foreach (string s in pathArray)
            {
                string extension = Path.GetExtension(s);
                string md5 = FileUtils.GetFileMD5(s);
                string name = Path.GetFileNameWithoutExtension(s);
                if (name == platformFolderName && string.IsNullOrEmpty(extension))
                {
                    name = name + "_AssetBundleManifest";
                }
                name = name.ToLower();
                try
                {
                    dic.Add(name, md5);
                }
                catch (Exception e)
                {
                    Debug.LogError("Name :" + name + "  MD5:" + md5 + "\n" + e);
                }
            }
            string data = JsonUtils.ToJson(dic);
            FileUtils.CreateTextFile(assetPath + UpdateAssetsConst.PathMD5FileName, data);
            AssetDatabase.Refresh();
        }


        public static void CreateOneFileBundle(string AssetBundlesOutputPath, string oldPath)
        {
            string fileName = Path.GetFileName(oldPath);
            string copyPath = "Assets/Temp/" + fileName;
            string s = Path.GetDirectoryName(copyPath);
            if (!Directory.Exists(s))
            {
                Directory.CreateDirectory(s);
            }
            File.Copy(oldPath, copyPath, true);
            AssetDatabase.Refresh();
            AssetImporter assetImporter = AssetImporter.GetAtPath(copyPath);

            if (assetImporter)
            {
                assetImporter.assetBundleName = Path.GetFileNameWithoutExtension(oldPath) + UpdateAssetsConst.EndsWith_assetbundle;
            }
            AssetBundleBuildUtils.BuildAssetBundle(AssetBundlesOutputPath);
            if (Directory.Exists(s))
            {
                Directory.Delete(s, true);
            }
        }
        /// <summary>
        /// 转换Editor下打包平台BuildTarget 成为 RuntimePlatform 方便统一AssetBundle路径
        /// </summary>
        /// <param name="buildTarget"></param>
        /// <returns></returns>
        public static RuntimePlatform BuildTarget2RuntimePlatform(BuildTarget buildTarget)
        {
            switch (buildTarget)
            {
                case BuildTarget.StandaloneOSX:
                    return RuntimePlatform.OSXPlayer;

                case BuildTarget.StandaloneWindows:
                case BuildTarget.StandaloneWindows64:
                    return RuntimePlatform.WindowsPlayer;

                case BuildTarget.StandaloneLinux64:
                case BuildTarget.StandaloneLinuxUniversal:
                    return RuntimePlatform.LinuxPlayer;

                case BuildTarget.Android:
                    return RuntimePlatform.Android;

                case BuildTarget.iOS:
                    return RuntimePlatform.IPhonePlayer;

                case BuildTarget.tvOS:
                    return RuntimePlatform.tvOS;

                case BuildTarget.XboxOne:
                    return RuntimePlatform.XboxOne;

                //case BuildTarget.PSP2:
                //    return RuntimePlatform.PSP2;

                case BuildTarget.PS4:
                    return RuntimePlatform.PS4;

                case BuildTarget.WebGL:
                    return RuntimePlatform.WebGLPlayer;

                case BuildTarget.WSAPlayer:
                    return RuntimePlatform.WSAPlayerX64;
            }

            return RuntimePlatform.WindowsPlayer;
        }

    }
}

